from flask import Blueprint, request, jsonify
from models import Submission, Homework, Problem, User, db
from utils import format_response, validate_submission_status
from decorators import student_required, teacher_required, get_current_user
from services.judge_service import JudgeService
import json
from datetime import datetime

submissions_bp = Blueprint('submissions', __name__)
judge_service = JudgeService()

@submissions_bp.route('/', methods=['POST'])
@student_required
def create_submission():
    """学生提交答案/代码"""
    try:
        current_user = get_current_user()
        if not current_user:
            return jsonify(format_response(message="用户未认证", code=401)), 401
        
        data = request.get_json()
        
        homework_id = data.get('homework_id')
        problem_id = data.get('problem_id')
        answer = data.get('answer')  # 答案（代码或文本）
        language = data.get('language')  # 编程语言
        
        if not homework_id or not problem_id or not answer:
            return jsonify(format_response(message="作业ID、题目ID和答案不能为空", code=400)), 400
        
        # 验证作业和题目是否存在
        homework = Homework.query.get(homework_id)
        if not homework:
            return jsonify(format_response(message="作业不存在", code=404)), 404
        
        problem = Problem.query.get(problem_id)
        if not problem:
            return jsonify(format_response(message="题目不存在", code=404)), 404
        
        # 检查题目是否在作业中
        homework_problems = json.loads(homework.problems)
        if problem_id not in homework_problems:
            return jsonify(format_response(message="该题目不属于此作业", code=400)), 400
        
        # 检查是否已提交过
        existing_submission = Submission.query.filter_by(
            homework_id=homework_id,
            problem_id=problem_id,
            student_id=current_user.id
        ).first()
        
        # 根据题目类型进行评测
        judge_result = None
        if problem.type == 'code':
            # 编程题：需要代码评测
            if not language:
                return jsonify(format_response(message="编程题需要指定编程语言", code=400)), 400
            
            test_cases = json.loads(problem.test_cases) if problem.test_cases else []
            judge_result = judge_service.judge_submission(
                code=answer,
                language=language,
                test_cases=test_cases,
                time_limit=problem.time_limit,
                memory_limit=problem.memory_limit
            )
            
        elif problem.type == 'choice':
            # 选择题
            judge_result = judge_service.judge_choice_question(answer, problem.answer)
            
        elif problem.type == 'blank':
            # 填空题
            judge_result = judge_service.judge_blank_question(answer, problem.answer)
            
        elif problem.type == 'short':
            # 简答题
            judge_result = judge_service.judge_short_answer(answer, problem.answer)
        
        if existing_submission:
            # 更新现有提交
            existing_submission.answer = answer
            existing_submission.language = language
            existing_submission.status = judge_result['status']
            existing_submission.score = judge_result['score']
            existing_submission.execution_time = judge_result.get('execution_time')
            existing_submission.memory_used = judge_result.get('memory_used')
            existing_submission.error_message = judge_result.get('message')
            existing_submission.test_results = json.dumps(judge_result.get('test_results', []))
            existing_submission.submit_time = datetime.utcnow()
            db.session.commit()
            
            return jsonify(format_response(existing_submission.to_dict(), "提交更新成功"))
        else:
            # 创建新提交
            new_submission = Submission(
                homework_id=homework_id,
                problem_id=problem_id,
                student_id=current_user.id,
                answer=answer,
                language=language,
                status=judge_result['status'],
                score=judge_result['score'],
                execution_time=judge_result.get('execution_time'),
                memory_used=judge_result.get('memory_used'),
                error_message=judge_result.get('message'),
                test_results=json.dumps(judge_result.get('test_results', []))
            )
            db.session.add(new_submission)
            db.session.commit()
            
            return jsonify(format_response(new_submission.to_dict(), "提交成功"))
            
    except Exception as e:
        db.session.rollback()
        return jsonify(format_response(message=str(e), code=500)), 500

@submissions_bp.route('/<int:submission_id>', methods=['GET'])
@student_required
def get_submission(submission_id):
    """获取提交详情"""
    try:
        current_user = get_current_user()
        submission = Submission.query.get(submission_id)
        
        if not submission:
            return jsonify(format_response(message="提交不存在", code=404)), 404
        
        # 检查权限：只能查看自己的提交，或教师/管理员可以查看所有
        if submission.student_id != current_user.id and current_user.role not in ['teacher', 'admin']:
            return jsonify(format_response(message="没有权限查看此提交", code=403)), 403
        
        submission_data = submission.to_dict()
        submission_data['problem'] = submission.problem.to_dict()
        submission_data['homework'] = submission.homework.to_dict()
        submission_data['student'] = submission.student.to_dict()
        
        return jsonify(format_response(submission_data))
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@submissions_bp.route('/homework/<int:homework_id>', methods=['GET'])
@student_required
def get_submissions_by_homework(homework_id):
    """获取作业的所有提交"""
    try:
        current_user = get_current_user()
        homework = Homework.query.get(homework_id)
        
        if not homework:
            return jsonify(format_response(message="作业不存在", code=404)), 404
        
        # 学生只能查看自己的提交，教师可以查看所有提交
        if current_user.role == 'student':
            submissions = Submission.query.filter_by(
                homework_id=homework_id,
                student_id=current_user.id
            ).all()
        else:
            submissions = Submission.query.filter_by(homework_id=homework_id).all()
        
        submissions_data = []
        for submission in submissions:
            data = submission.to_dict()
            data['problem'] = submission.problem.to_dict()
            data['student'] = submission.student.to_dict()
            submissions_data.append(data)
        
        return jsonify(format_response(submissions_data))
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@submissions_bp.route('/problem/<int:problem_id>', methods=['GET'])
@student_required
def get_submissions_by_problem(problem_id):
    """获取题目的所有提交"""
    try:
        current_user = get_current_user()
        problem = Problem.query.get(problem_id)
        
        if not problem:
            return jsonify(format_response(message="题目不存在", code=404)), 404
        
        # 学生只能查看自己的提交，教师可以查看所有提交
        if current_user.role == 'student':
            submissions = Submission.query.filter_by(
                problem_id=problem_id,
                student_id=current_user.id
            ).all()
        else:
            submissions = Submission.query.filter_by(problem_id=problem_id).all()
        
        submissions_data = []
        for submission in submissions:
            data = submission.to_dict()
            data['homework'] = submission.homework.to_dict()
            data['student'] = submission.student.to_dict()
            submissions_data.append(data)
        
        return jsonify(format_response(submissions_data))
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@submissions_bp.route('/my-submissions', methods=['GET'])
@student_required
def get_my_submissions():
    """获取当前用户的所有提交"""
    try:
        current_user = get_current_user()
        
        if not current_user:
            return jsonify(format_response(message="用户未认证", code=401)), 401
        
        # 获取查询参数
        status = request.args.get('status')
        homework_id = request.args.get('homework_id')
        
        query = Submission.query.filter_by(student_id=current_user.id)
        
        if status:
            query = query.filter(Submission.status == status)
        if homework_id:
            query = query.filter(Submission.homework_id == homework_id)
        
        submissions = query.order_by(Submission.submit_time.desc()).all()
        
        submissions_data = []
        for submission in submissions:
            data = submission.to_dict()
            data['problem'] = submission.problem.to_dict()
            data['homework'] = submission.homework.to_dict()
            submissions_data.append(data)
        
        return jsonify(format_response(submissions_data))
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@submissions_bp.route('/stats', methods=['GET'])
@student_required
def get_submission_stats():
    """获取提交统计信息"""
    try:
        current_user = get_current_user()
        
        # 获取查询参数
        homework_id = request.args.get('homework_id')
        
        query = Submission.query.filter_by(student_id=current_user.id)
        
        if homework_id:
            query = query.filter(Submission.homework_id == homework_id)
        
        submissions = query.all()
        
        # 统计各种状态
        total_submissions = len(submissions)
        ac_count = sum(1 for s in submissions if s.status == 'AC')
        wa_count = sum(1 for s in submissions if s.status == 'WA')
        re_count = sum(1 for s in submissions if s.status == 'RE')
        tle_count = sum(1 for s in submissions if s.status == 'TLE')
        ce_count = sum(1 for s in submissions if s.status == 'CE')
        
        # 计算平均分
        total_score = sum(s.score for s in submissions)
        avg_score = total_score / total_submissions if total_submissions > 0 else 0
        
        stats = {
            'total': total_submissions,
            'ac': ac_count,
            'wa': wa_count,
            're': re_count,
            'tle': tle_count,
            'ce': ce_count,
            'avg_score': round(avg_score, 2),
            'total_score': total_score
        }
        
        return jsonify(format_response(stats))
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@submissions_bp.route('/<int:submission_id>/rejudge', methods=['POST'])
@teacher_required
def rejudge_submission(submission_id):
    """重新评测提交"""
    try:
        submission = Submission.query.get(submission_id)
        if not submission:
            return jsonify(format_response(message="提交不存在", code=404)), 404
        
        problem = submission.problem
        
        # 重新评测
        judge_result = None
        if problem.type == 'code':
            test_cases = json.loads(problem.test_cases) if problem.test_cases else []
            judge_result = judge_service.judge_submission(
                code=submission.answer,
                language=submission.language,
                test_cases=test_cases,
                time_limit=problem.time_limit,
                memory_limit=problem.memory_limit
            )
        elif problem.type == 'choice':
            judge_result = judge_service.judge_choice_question(submission.answer, problem.answer)
        elif problem.type == 'blank':
            judge_result = judge_service.judge_blank_question(submission.answer, problem.answer)
        elif problem.type == 'short':
            judge_result = judge_service.judge_short_answer(submission.answer, problem.answer)
        
        # 更新提交结果
        submission.status = judge_result['status']
        submission.score = judge_result['score']
        submission.execution_time = judge_result.get('execution_time')
        submission.memory_used = judge_result.get('memory_used')
        submission.error_message = judge_result.get('message')
        submission.test_results = json.dumps(judge_result.get('test_results', []))
        
        db.session.commit()
        
        return jsonify(format_response(submission.to_dict(), "重新评测完成"))
    except Exception as e:
        db.session.rollback()
        return jsonify(format_response(message=str(e), code=500)), 500
